package br.cesed.facisa.si.tap.projetos.estagio1.logica;

import br.cesed.facisa.si.tap.projetos.estagio1.entidades.Cliente;
import br.cesed.facisa.si.tap.projetos.estagio1.entidades.Filme;
import br.cesed.facisa.si.tap.projetos.estagio1.entidades.Locacao;
import br.cesed.facisa.si.tap.projetos.estagio1.excecoes.FilmeNaoPagoException;
import br.cesed.facisa.si.tap.projetos.estagio1.excecoes.LocacaoNaoEncontradaException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Locadora
{
    public static void main( String[] args )
    {
        System.out.println( "Programa Locadora Executado!" );
    }

    private List<Filme> filmes;
    private List<Locacao> locacoes;

    public Locadora(  )
    {
        filmes = new ArrayList<Filme>(  );
        locacoes = new ArrayList<Locacao>(  );
    }

    /**
     * Este m�todo adiciona um filme na locadora.
     * @param filme Filme a ser adicionado.
     */
    public void adicionarFilme( Filme filme )
    {
        filmes.add( filme );
    }

    /**
     * Este m�todo retorna os filmes cadastrados na locadora
     * em ordem alfab�tica pelo nome do filme.
     */
    public List<Filme> listarFilmes(  )
    {
        //Ordenando os filmes
        Collections.sort( filmes );

        return filmes;
    }

    /**
     * Este m�todo retorna os nomes dos autores dos filmes cadastrados na
     * locadora;
     * Aten��o:
     *  - um mesmo autor n�o pode aparecer mais de uma vez;
     *  - os nomes dos autores devem ser retornados em ordem alfab�tica.
     */
    public List<String> getAutores(  )
    {
        List<String> autores = new ArrayList<String>(  );

        for ( Filme f : filmes )
        {
            if ( ! autores.contains( f.getAutor(  ) ) )
            {
                autores.add( f.getAutor(  ) );
            }
        }

        Collections.sort( autores );

        return autores;
    }

    /**
     * Este m�todo retorna os nomes dos g�neros dos filmes cadastrados na
     * locadora;
     * Aten��oo:
     *  - um mesmo g�nero n�o pode aparecer mais de uma vez;
     *  - os nomes dos g�neros devem ser retornados em ordem alfab�tica.
     */
    public List<String> getGeneros(  )
    {
        List<String> generos = new ArrayList<String>(  );

        for ( Filme f : filmes )
        {
            if ( ! generos.contains( f.getGenero(  ) ) )
            {
                generos.add( f.getGenero(  ) );
            }
        }

        Collections.sort( generos );

        return generos;
    }

    /**
     * Este m�todo � respons�vel por realizar uma loca��o.
     * @param filme Filme que est� sendo locado.
     * @param cliente Cliente que est� locando um filme.
     */
    public void realizarLocacao( Filme filme, Cliente cliente )
    {
        locacoes.add( new Locacao( filme, cliente ) );
    }

    /**
     * Este m�todo ser� chamado quando um filme for devolvido
     * @param filme
     */
    public void devolverFilme( Filme filme )
                       throws FilmeNaoPagoException, LocacaoNaoEncontradaException
    {
        Locacao locacao = getLocacao( filme );

        if ( ! locacao.isPago(  ) )
        {
            throw new FilmeNaoPagoException(  );
        }

        locacoes.remove( locacao );
    }

    /**
     * Este m�todo deve ser chamado para efetuar o pagamento referente a uma loca��o.
     * @param filme Filme associado � loca��o.
     * @throws LocacaoNaoEncontradaException Caso n�o exista uma loca��o associada ao
     * filme informado, esta exce��o ser� lan�ada.
     */
    public void pagarLocacao( Filme filme )
                      throws LocacaoNaoEncontradaException
    {
        Locacao locacao = getLocacao( filme );
        locacao.setPago( true );
    }

    /**
     * Este m�todo serve para retornar uma loca��o associada a um filme.
     * @param filme Filme para o qual se quer obter a loca�ao.
     * @return Loca��o associada ao filme informado.
     * @throws LocacaoNaoEncontradaException Caso n�o exista uma loca��o associada
     * ao filme informado, esta exce��o ser� lan�ada.
     */
    public Locacao getLocacao( Filme filme )
                       throws LocacaoNaoEncontradaException
    {
        for ( Locacao locacao : locacoes )
        {
            if ( locacao.getFilme(  ).equals( filme ) )
            {
                return locacao;
            }
        }

        throw new LocacaoNaoEncontradaException(  );
    }

    /**
     * Este m�todo retorna todas as locacoes atualmente em atraso.
     */
    public List<Locacao> getLocacoesAtrasadas(  )
    {
        List<Locacao> locacoesAtrasadas = new ArrayList<Locacao>(  );

        for ( Locacao locacao : locacoes )
        {
            if ( locacao.isAtrasado(  ) )
            {
                locacoesAtrasadas.add( locacao );
            }
        }

        return locacoesAtrasadas;
    }
}
